
using Microsoft.Net.Http.Headers;
using LyxWaf.Services.Files;
using NLog.Extensions.Logging;
using System.Text.Unicode;
using System.Text;
using Yarp.ReverseProxy.Model;
using LyxWaf.Services.SpeedLimit;
using Microsoft.Extensions.Options;
using System.Threading.RateLimiting;

namespace LyxWaf.Middleware;

public class SpeedLimitMiddleware(RequestDelegate next)
{
    private static readonly ILogger _logger = LoggerFactory.Create(builder => builder.AddNLog()).CreateLogger<StatisticLogMiddleware>();
    private readonly RequestDelegate _next = next;

    public async Task InvokeAsync(HttpContext context)
    {
        var end = context.GetEndpoint()!;
        var meta = end.Metadata;
        var route = meta.GetMetadata<RouteModel>();
        if (route != null && route.Config.Metadata != null)
        {
            var speedService = context.RequestServices.GetRequiredService<ISpeedLimitService>();
            if (route.Config.Metadata.TryGetValue("RateLimiter", out var policy))
            {
                var rate = speedService.Get(policy);
                if (rate == null)
                {
                    _logger.LogWarning("不存在策略:{}", policy);
                }
                else
                {
                    using RateLimitLease lease = await rate.AcquireAsync(context, 1);
                    if (!lease.IsAcquired)
                    {
                        var reject = speedService.GetRejectCode();
                        context.Response.StatusCode = reject;
                        return;
                    }
                }
            }
        }
        await _next(context);
    }
}